<?php

namespace App\Http\Controllers\Api;

use App\ActiveParty;
use App\Activity;
use App\ActivityJoin;
use App\Http\Services\ToolsManager;
use App\Http\Services\UserManager;
use App\Orders;
use App\User;
use App\VipInfo;
use App\VipPackage;
use EasyWeChat\Factory;
use Endroid\QrCode\QrCode;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use Intervention\Image\Facades\Image;

class PaymentController extends Controller
{
    public function weChatPayment(Request $request){
        /** @var User $user */
        $user = UserManager::isLogin($request);
        if(!$user)
            return response()->json(['level' => 'error','message' => '请先登录!','data' => 'no_login']);

        $orderNum = $request->get('order_num');
        $type     = !is_null($request->get('type')) ? $request->get('type') : 'default';

        /** @var Orders $thisOrder */
        $thisOrder = Orders::whereOrderNum($orderNum)->whereUserId($user->id)->first();
        if(!$thisOrder)
            return response()->json(['level' => 'error','message' => '订单不存在']);

        if($thisOrder->is_pay == 1)
            return response()->json(['level' => 'error','message' => '订单已支付']);

        if($thisOrder->status == 1 && (strtotime($thisOrder->created_at) + (30 * 60)) < time()){
            $thisOrder->status = 6;
            $thisOrder->save();

            return response()->json(['level' => 'error','message' => '订单已失效']);
        }

        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥
        ];

        if($thisOrder->type == 'activity'){
            /** @var Activity $isActivity */
            $isActivity = Activity::whereId($thisOrder->activity_id)->whereStatus(1)->first();
            if(!$isActivity)
                return response()->json(['level' => 'error','message' => '活动已下架']);

            if(strtotime($isActivity->end_time) <= time())
                return response()->json(['level' => 'error','message' => '活动已结束']);

            $isJoinActivity = ActivityJoin::whereUserId($user->id)->whereActivityId($isActivity->id)->whereOrderNum($thisOrder->order_num)->whereStatus(1)->first();
            if($isJoinActivity)
                return response()->json(['level' => 'error','message' => '您已经报名过了']);

            $app = Factory::payment($config);
            $result = $app->order->unify([
                'body' => '报名费用',
                'out_trade_no' => $thisOrder->order_num,
                'total_fee' => (float)$thisOrder->s_amount * 100,
                'spbill_create_ip' => '', // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
                'notify_url' => route('Api.Payment.WeChatPayCallback'), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $user->wx_openid,
            ]);
        }elseif($thisOrder->type == 'vip'){
            $vipPackage = VipPackage::whereId($thisOrder->vip_package_id)->whereStatus(1)->first();
            if(!$vipPackage)
                return response()->json(['level' => 'error','message' => '该套餐不存在']);

            $vipInfo = VipInfo::whereUserId($user->id)->first();
            if($vipInfo && $vipInfo->status != 1)
                return response()->json(['level' => 'error','message' => '用户得vip状态异常']);

            if($vipInfo && $vipInfo->vip_package_id != $vipPackage->id && strtotime($vipInfo->end_time) > time())
                return response()->json(['level' => 'error','message' => '您已绑定其他套餐']);

            $app = Factory::payment($config);
            $result = $app->order->unify([
                'body' => 'vip购买',
                'out_trade_no' => $thisOrder->order_num,
                'total_fee' => (float)$thisOrder->s_amount * 100,
                'spbill_create_ip' => '', // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
                'notify_url' => route('Api.Payment.WeChatPayCallback'), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $user->wx_openid,
            ]);
        }else{
            return response()->json(['level' => 'error','message' => '订单类型不正确']);
        }

        if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
            $jssdk = $app->jssdk;
            $prepayId = $result['prepay_id'];
            $json = $jssdk->bridgeConfig($prepayId); // 返回 json 字符串，如果想返回数组，传第二个参数 false

            return response()->json(['level' => 'success','message' => '订单创建成功','data'=>json_decode($json)]);
        }else{
            return response()->json(['level' => 'error','message' => '订单创建失败','data' => $result]);
        }
    }

    /**
     * 获取支付二维码
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws \Endroid\QrCode\Exceptions\ImageTypeInvalidException
     */
    public function getPayQrCode(Request $request){
        $codeUrl = !is_null($request->get('code_url')) ? $request->get('code_url') : '';

        $url = $codeUrl;
        $qrCode = new QrCode();
        $qrCode
            ->setText($url)
            ->setSize(250)
            ->setPadding(10)
            ->setErrorCorrection('high')
            ->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0])
            ->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0])
            ->setImageType(QrCode::IMAGE_TYPE_PNG)
        ;

        $qrcodeContent = $qrCode->getImage();

        $qrcodeContentImg = Image::make($qrcodeContent);

        $response = response()->make($qrcodeContentImg->encode('png'));
        $response->header('Content-Type', 'image/png');

        return $response;
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPayStatus(Request $request){
        $orderNum = !is_null($request->get('order_num')) ? $request->get('order_num') : '';
        $type     = !is_null($request->get('type')) ? $request->get('type') : 2;

        $order = Orders::whereOrderNum($orderNum)->first();
        if(!$order)
            return response()->json(['level' => 'error','message' => '订单不存在']);

        if($type == 2){
            if($order->is_pay == 1){
                return response()->json(['level' => 'success','message' => '订单支付成功','data' => $order->is_pay]);
            }else{
                return response()->json(['level' => 'error','message' => '订单支付失败','data' => $order->is_pay]);
            }
        }elseif($type == 1){
            return response()->json(['level' => 'error','message' => '订单已取消']);
        }else{
            return response()->json(['level' => 'error','message' => '系统错误']);
        }

    }

    //微信支付回调
    public function WeChatPayCallback(Request $request){
        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥
        ];

        $app = Factory::payment($config);

        $response = $app->handlePaidNotify(function ($message, $fail) {
            $ordersNum = $message['out_trade_no'];

            /** @var Orders $order */
            $order = Orders::whereOrderNum($ordersNum)->first();

            if(!$order || ($order && $order->is_pay == 1)){
                return true;
            }

            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                // 用户是否支付成功
                if (array_get($message, 'result_code') === 'SUCCESS') {
                    $order->pay_time = date('Y-m-d H:i:s',time()); // 更新支付时间为当前时间
                    $order->pay_type = 'wechat';
                    $order->is_pay   = 1;

                    if($order->type == 'activity'){
                        /** @var Activity $thatActivity */
                        $thatActivity = Activity::whereId($order->activity_id)->whereStatus(1)->first();
                        if($thatActivity){
                            /** @var ActivityJoin $thatJoinActivity */
                            $thatJoinActivity = ActivityJoin::whereUserId($order->user_id)->whereActivityId($order->activity_id)->whereOrderNum($order->order_num)->whereStatus(0)->first();
                            if($thatJoinActivity){
                                if($thatActivity->is_review == 1){
                                    $thatJoinActivity->status = 2;
                                    $thatJoinActivity->save();
                                }else{
                                    $thatJoinActivity->status = 1;
                                    $thatJoinActivity->save();
                                }
                            }else{
                                return response()->json(['level' => 'error','message' => '系统错误']);
                            }

                        }else{
                            return response()->json(['level' => 'error','message' => '活动已下架']);
                        }
                    }elseif($order->type == 'vip'){
                        $vipPackage = VipPackage::whereId($order->vip_package_id)->whereStatus(1)->first();
                        if(!$vipPackage)
                            return response()->json(['level' => 'error','message' => '该套餐不存在']);

                        $vipInfo = VipInfo::whereUserId($order->user_id)->first();
                        if($vipInfo){
                            if($vipInfo->vip_package_id == $vipPackage->id){
                                if(strtotime($vipInfo->end_time) > time()){
                                    $vipInfo->vip_package_id     = $vipPackage->id;
                                    $vipInfo->end_time           = date("Y-m-d H:i:s",strtotime($vipInfo->end_time) + ($vipPackage->keep_time * 30 * 24 * 3600) * (int)$order->vip_package_num);
                                    $vipInfo->save();
                                }else{
                                    $vipInfo->vip_package_id     = $vipPackage->id;
                                    $vipInfo->start_time         = date("Y-m-d H:i:s",time());
                                    $vipInfo->end_time           = date("Y-m-d H:i:s",time() + ($vipPackage->keep_time * 30 * 24 * 3600) * (int)$order->vip_package_num);
                                    $vipInfo->save();
                                }
                            }else{
                                if(strtotime($vipInfo->end_time) > time()){
                                    return response()->json(['level' => 'error','message' => '该用户已经保定过其他套餐了']);
                                }else{
                                    $vipInfo->vip_package_id     = $vipPackage->id;
                                    $vipInfo->start_time         = date("Y-m-d H:i:s",time());
                                    $vipInfo->end_time           = date("Y-m-d H:i:s",time() + ($vipPackage->keep_time * 30 * 24 * 3600) * (int)$order->vip_package_num);
                                    $vipInfo->save();
                                }
                            }
                        }else{
                            $vipInfo = new VipInfo();
                            $vipInfo->user_id            = $order->user_id;
                            $vipInfo->vip_package_id     = $vipPackage->id;
                            $vipInfo->start_time         = date("Y-m-d H:i:s",time());
                            $vipInfo->end_time           = date("Y-m-d H:i:s",time() + ($vipPackage->keep_time * 30 * 24 * 3600) * (int)$order->vip_package_num);
                            $vipInfo->status             = 1;
                            $vipInfo->save();
                        }
                    }else{
                        return response()->json(['level' => 'error','message' => '订单类型不正确']);
                    }

                    $order->status   = 1;

                    // 用户支付失败
                } elseif (array_get($message, 'result_code') === 'FAIL') {
                    $order->status = 0;
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }

            $order->save(); // 保存订单

            return true; // 返回处理完成

        });

        return $response;
    }

    /**
     * 退款接口（订单不可为空）
     * @param Orders $thisOrder
     * @param $reason
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     */
    public static function Refund(Orders $thisOrder,$reason){
        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥

            'cert_path'          => base_path().'/public/apiclient_cert.pem',
            'key_path'           => base_path().'/public/apiclient_key.pem',

        ];

        $app = Factory::payment($config);

        $refundNum = ToolsManager::makeBRefundNum();

        $result = $app->refund->byOutTradeNumber($thisOrder->order_num, $refundNum, $thisOrder->s_amount * 100, $thisOrder->s_amount * 100, [
            // 可在此处传入其他参数，详细参数见微信支付文档
            'refund_desc' => $reason,
        ]);

        return $result;
    }

    /**
     * 退款查询接口（订单不可为空）
     * @param Orders $thisOrder
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     */
    public static function selectRefund(Orders $thisOrder){
        $config = [
            // 必要配置
            'app_id'             => env('WXAPP_KEY'),
            'mch_id'             => env('WECHAT_PAYMENT_MERCHANT_ID'),
            'key'                => env('WECHAT_PAYMENT_KEY'),   // API 密钥

            'cert_path'          => base_path().'/public/apiclient_cert.pem',
            'key_path'           => base_path().'/public/apiclient_key.pem',

        ];

        $app = Factory::payment($config);

        $result = $app->refund->queryByOutTradeNumber($thisOrder->order_num);

        return $result;
    }
}
